#include"NROM.h"

uint8_t NROMRead(MAPPER* mapper, uint16_t addr);
void NROMWrite(MAPPER* mapper, uint16_t addr, uint8_t dat);
bool NROMReset(MAPPER* mapper)
{
	mapper->read = NROMRead;
	mapper->write = NROMWrite;
	if (mapper->cart->Header.ChrSize !=1)
		return false;
	((NROM*)mapper)->ChrRom = mapper->cart->ChrRom;
	if (mapper->cart->Header.PrgSize == 2)
	{
		((NROM*)mapper)->PrgRom0 = mapper->cart->PrgRom;
		((NROM*)mapper)->PrgRom1 = mapper->cart->PrgRom + 0x4000;
	}
	else if (mapper->cart->Header.PrgSize == 1)
	{
		((NROM*)mapper)->PrgRom0 = ((NROM*)mapper)->PrgRom1 = mapper->cart->PrgRom;
	}
	else
		return false;
	if (mapper->cart->Header.Flag6 & FOUR_SCREEN)
		return false;
	if (mapper->cart->Header.Flag6 & MIRROR_VERTICAL)
	{
		((NROM*)mapper)->nametable0 = ((NROM*)mapper)->nametable2 = mapper->vram;
		((NROM*)mapper)->nametable1 = ((NROM*)mapper)->nametable3 = &mapper->vram[0x400];
	}
	else
	{
		((NROM*)mapper)->nametable0 = ((NROM*)mapper)->nametable1 = mapper->vram;
		((NROM*)mapper)->nametable2 = ((NROM*)mapper)->nametable3 = &mapper->vram[0x400];
	}
	return true;
}
uint8_t NROMRead(MAPPER* mapper, uint16_t addr)
{
	if (addr < 0x2000)
	{
		return ((NROM*)mapper)->ChrRom[addr & 0x1fff];
	}
	else if (addr < 0x3f00)
	{
		addr &= 0x2fff;
		if (addr < 0x2400)
			return ((NROM*)mapper)->nametable0[addr & 0x03ff];
		else if (addr < 0x2800)
			return ((NROM*)mapper)->nametable1[addr & 0x03ff];
		else if (addr < 0x2c00)
			return ((NROM*)mapper)->nametable2[addr & 0x03ff];
		else
			return ((NROM*)mapper)->nametable3[addr & 0x03ff];
	}

	else if (addr < 0x8000)
		return 0;

	else if (addr>=0x8000&&addr < 0xC000)
	{
		return ((NROM*)mapper)->PrgRom0[addr & 0x3fff];
	}
	else
	{
		return ((NROM*)mapper)->PrgRom1[addr & 0x3fff];
	}
}
void NROMWrite(MAPPER* mapper, uint16_t addr, uint8_t dat)
{
	if (addr >= 0x2000 && addr < 0x3f00)
	{
		addr &= 0x2fff;
		if (addr < 0x2400)
			((NROM*)mapper)->nametable0[addr & 0x03ff] = dat;
		else if (addr < 0x2800)
			((NROM*)mapper)->nametable1[addr & 0x03ff] = dat;
		else if (addr < 0x2C00)
			((NROM*)mapper)->nametable2[addr & 0x03ff] = dat;
		else
			((NROM*)mapper)->nametable3[addr & 0x03ff] = dat;
	}
}
